package com.tgu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tgu.entity.model.OrdersEntity;
import com.tgu.entity.model.UsersEntity;
import com.tgu.entity.request.OrderReq;
import com.tgu.entity.request.TakeOrderReq;
import com.tgu.entity.request.UserCancelReq;
import com.tgu.entity.response.OrderResp;
import com.tgu.mapper.OrdersDao;
import com.tgu.mapper.UsersDao;
import com.tgu.service.IOrdersService;
import com.tgu.utils.result.Result;
import com.tgu.utils.result.SystemCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service("ordersService")
public class OrdersServiceImpl extends ServiceImpl<OrdersDao, OrdersEntity> implements IOrdersService {

    @Autowired
    private OrdersDao ordersDao;
    @Autowired
    private UsersDao usersDao;


    @Override
    @Transactional
    public Result postOrderByEntity(OrderReq orderReq) {
        // 做手机号校验
        if (!orderReq.getOrderPostUserPhone().matches("^((13[0-9])|(14[0,1,4-9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0-8])|(18[0-9])|(19[0-3,5-9]))\\d{8}$")
                || !orderReq.getOrderAcceptUserPhone().matches("^((13[0-9])|(14[0,1,4-9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0-8])|(18[0-9])|(19[0-3,5-9]))\\d{8}$")) {
            return Result.error(SystemCodeEnum.PHONE_NUMBER_ERROR);
        }
        // 做金钱的校验
        if (!orderReq.getOrderMoney().matches("\\d+(\\.\\d{1,2})?")) {
            return Result.error(SystemCodeEnum.MONEY_NUMBER_ERROR);
        }

        UsersEntity usersEntity = usersDao.selectById(orderReq.getUserId());
        if (usersEntity == null) {
            return Result.error(SystemCodeEnum.LOGIN_TIME_OUT);
        }
        if (usersEntity.getUserMoney() < Long.parseLong(orderReq.getOrderMoney())) {
            return Result.error(SystemCodeEnum.MONEY_NOT_ENOUGH);
        }
        usersEntity.setUserMoney(usersEntity.getUserMoney() - Long.parseLong(orderReq.getOrderMoney()));
        int i = usersDao.updateById(usersEntity);
        if (i == 0) {
            return Result.error(SystemCodeEnum.SYSTEM_SERVER_ERROR);
        }

        OrdersEntity order = new OrdersEntity();
        Date data = new Date();
        order.setOrderPostTime(data);
        order.setInfoDate(data);
        order.setOrderMoney(Long.parseLong(orderReq.getOrderMoney()));
        order.setOrderRemark(orderReq.getOrderRemark());
        order.setAddressGoods(orderReq.getAddressGoods());
        order.setAddressAcceptor(orderReq.getAddressAcceptor());
        order.setUserId(orderReq.getUserId());
        order.setOrderPostUserPhone(orderReq.getOrderPostUserPhone());
        order.setOrderAcceptUserPhone(orderReq.getOrderAcceptUserPhone());
        order.setGoodsCode(orderReq.getGoodsCode());
        order.setOrderAcceptUserName(orderReq.getOrderAcceptUserName());
        order.setOrderPostUserName(orderReq.getOrderPostUserName());

        int insert = ordersDao.insert(order);
        if (insert == 0) return Result.error(SystemCodeEnum.POST_ERROR);

        return Result.ok(SystemCodeEnum.POST_SUCCESS);
    }

    public Result getMarketPage(Integer pageNumb, Integer option1, String option2) {
        Page page = new Page<OrdersEntity>(pageNumb, 8);
        LambdaQueryWrapper<OrdersEntity> lqw = new LambdaQueryWrapper<>();
        lqw.isNull(OrdersEntity::getUserRiderId)
                .isNull(OrdersEntity::getOrderAcceptTime)
                .isNull(OrdersEntity::getOrderFinishTime);

        String option = option1.toString() + option2;
        switch (option) {
            case "0a":
                break;
            case "0b":
                lqw.orderByAsc(OrdersEntity::getOrderPostTime);
                break;
            case "0c":
                lqw.orderByDesc(OrdersEntity::getOrderPostTime);
                break;
            case "0d":
                lqw.orderByAsc(OrdersEntity::getOrderMoney);
                break;
            case "0e":
                lqw.orderByDesc(OrdersEntity::getOrderMoney);
                break;
            case "1a":
                break;
            case "1b":
                lqw.orderByAsc(OrdersEntity::getOrderPostTime);
                break;
            case "1c":
                lqw.orderByDesc(OrdersEntity::getOrderPostTime);
                break;
            case "1d":
                lqw.orderByAsc(OrdersEntity::getOrderMoney);
                break;
            case "1e":
                lqw.orderByDesc(OrdersEntity::getOrderMoney);
                break;
        }
        ordersDao.selectPage(page, lqw);
        List<OrdersEntity> records = page.getRecords();

        List<OrderResp> orderVos = new ArrayList<OrderResp>();
        for (OrdersEntity record : records) {
            OrderResp orderVo = new OrderResp();
            orderVo.setId(record.getId());
            orderVo.setOrderPostTime(record.getOrderPostTime());
            orderVo.setAddressGoods(record.getAddressGoods());
            orderVo.setAddressAcceptor(record.getAddressAcceptor());
            String codes = record.getGoodsCode();
            String[] codesArray = codes.split(",");
            orderVo.setCount(codesArray.length);
            orderVo.setOrderRemark(record.getOrderRemark() == null ? "" : record.getOrderRemark());
            orderVo.setOrderMoney(record.getOrderMoney());
            orderVos.add(orderVo);
        }

        return Result.ok(orderVos);
    }

    @Override
    public Result getByPerson(String id) {
        LambdaQueryWrapper<OrdersEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(id != null && !id.equals(""), OrdersEntity::getUserId, id);
        List<OrdersEntity> ordersEntities = ordersDao.selectList(lqw);
        return Result.ok(SystemCodeEnum.SELECT_SUCCESS).setData(ordersEntities);
    }

    @Override
    public Result takeOrderOne(TakeOrderReq takeOrderReq) {

        UsersEntity acceptor = usersDao.selectById(takeOrderReq.getRiderId());

        if (acceptor == null) {
            return Result.error(SystemCodeEnum.USER_NOT_EXIST);
        }

        if (acceptor.getUserType() == 0) {
            return Result.error(SystemCodeEnum.USER_TYPE_ERROR);
        }

        OrdersEntity order = ordersDao.selectById(takeOrderReq.getOrderId());

        if (order == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }

        order.setUserRiderId(takeOrderReq.getRiderId());
        order.setOrderAcceptTime(new Date());
        ordersDao.updateById(order);

        return Result.ok(SystemCodeEnum.TAKE_ORDER_SUCCESS);
    }

    @Override
    public Result getByRider(String id) {
        LambdaQueryWrapper<OrdersEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(id != null && !id.equals(""), OrdersEntity::getUserRiderId, id);
        List<OrdersEntity> ordersEntities = ordersDao.selectList(lqw);

        if (ordersEntities == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }

        return Result.ok(SystemCodeEnum.SELECT_SUCCESS).setData(ordersEntities);
    }

    @Override
    public Result getOrderById(TakeOrderReq takeOrderReq) {
        // TODO takeOrderReq里面有骑手id，用来判断是否登录中，不登录不允许获取信息，防止信息泄露
        // 但是还没装redis，这部分功能还没做
        OrdersEntity ordersEntity = ordersDao.selectById(takeOrderReq.getOrderId());

        if (ordersEntity == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }

        return Result.ok(SystemCodeEnum.SELECT_SUCCESS).setData(ordersEntity);
    }

    @Override
    @Transactional
    public Result finishOrder(TakeOrderReq takeOrderReq) {
        UsersEntity usersEntity = usersDao.selectById(takeOrderReq.getRiderId());
        if (usersEntity == null) {
            return Result.error(SystemCodeEnum.LOGIN_TIME_OUT);
        }
        if (usersEntity.getUserType() == 0) {
            return Result.error(SystemCodeEnum.USER_TYPE_ERROR);
        }

        OrdersEntity ordersEntity = ordersDao.selectById(takeOrderReq.getOrderId());
        if (ordersEntity == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }
        ordersEntity.setOrderFinishTime(new Date());
        int i = ordersDao.updateById(ordersEntity);
        if (i == 0) {
            return Result.error(SystemCodeEnum.SYSTEM_SERVER_ERROR);
        }

        usersEntity.setUserMoney(usersEntity.getUserMoney() + ordersEntity.getOrderMoney());
        int i1 = usersDao.updateById(usersEntity);
        if (i1 == 0) {
            return Result.error(SystemCodeEnum.SYSTEM_SERVER_ERROR);
        }

        return Result.ok(SystemCodeEnum.FINISH_SUCCESS);
    }

    @Override
    @Transactional
    public Result userCancelOrder(UserCancelReq cancelReq) {

        UsersEntity usersEntity = usersDao.selectById(cancelReq.getUserId());
        if (usersEntity == null) {
            return Result.error(SystemCodeEnum.LOGIN_TIME_OUT);
        }

        OrdersEntity ordersEntity = ordersDao.selectById(cancelReq.getOrderId());
        if (ordersEntity == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }
        usersEntity.setUserMoney(usersEntity.getUserMoney() + ordersEntity.getOrderMoney());
        int i1 = usersDao.updateById(usersEntity);
        if (i1 == 0) {
            return Result.error(SystemCodeEnum.SYSTEM_SERVER_ERROR);
        }

        int i = ordersDao.deleteById(cancelReq.getOrderId());
        if (i == 0) {
            return Result.error(SystemCodeEnum.USER_CANCEL_ERROR);
        }

        return Result.ok(SystemCodeEnum.USER_CANCEL_SUCCESS);
    }

    @Override
    public Result riderAbandonOrder(UserCancelReq cancelReq) {
        UsersEntity usersEntity = usersDao.selectById(cancelReq.getUserId());
        if (usersEntity == null) {
            return Result.error(SystemCodeEnum.USER_NOT_EXIST);
        }
        if (usersEntity.getUserType() == 0) {
            return Result.error(SystemCodeEnum.USER_TYPE_ERROR);
        }

        OrdersEntity ordersEntity = ordersDao.selectById(cancelReq.getOrderId());
        if (ordersEntity == null) {
            return Result.error(SystemCodeEnum.ORDER_NOT_EXIST);
        }

        ordersEntity.setOrderAcceptTime(null);
        ordersEntity.setUserRiderId(null);
        LambdaQueryWrapper<OrdersEntity> lqw = new LambdaQueryWrapper<>();
        lqw.isNull(OrdersEntity::getOrderFinishTime)
                .eq(ordersEntity.getId() != null, OrdersEntity::getId, ordersEntity.getId());
        int update = ordersDao.update(ordersEntity, lqw);

        if (update == 0) {
            return Result.error(SystemCodeEnum.RIDER_CANCEL_ERROR);
        }

        return Result.ok(SystemCodeEnum.RIDER_CANCEL_SUCCESS);
    }

}
